package com.info.zhiduoduo.core.service.impl;

import com.baomidou.mybatisplus.mapper.Condition;
import com.info.zhiduoduo.common.configs.CommonConfig;
import com.info.zhiduoduo.common.constants.Constants;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.exception.SmartException;
import com.info.zhiduoduo.common.utils.MD5Util;
import com.info.zhiduoduo.common.utils.NumberUtil;
import com.info.zhiduoduo.core.configs.Redis.RedisKey;
import com.info.zhiduoduo.core.service.CoreCompanyService;
import com.info.zhiduoduo.core.service.common.RedisService;
import com.info.zhiduoduo.repository.dto.company.CompanyDetailDto;
import com.info.zhiduoduo.repository.dto.company.CompanyPayBalanceDto;
import com.info.zhiduoduo.repository.entity.company.Company;
import com.info.zhiduoduo.repository.entity.company.CompanyAccount;
import com.info.zhiduoduo.repository.entity.company.CompanyParty;
import com.info.zhiduoduo.repository.entity.company.CompanyPayment;
import com.info.zhiduoduo.repository.entity.system.TaxSource;
import com.info.zhiduoduo.repository.mapper.company.CompanyMapper;
import com.info.zhiduoduo.repository.mapper.company.CompanyPartyMapper;
import com.info.zhiduoduo.repository.mapper.company.CompanyPaymentMapper;
import com.taobao.api.internal.util.DESUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CoreCompanyServiceImpl implements CoreCompanyService {

	@Autowired
	CompanyMapper companyMapper;
	@Autowired
	CompanyPartyMapper companyPartyMapper;
	@Autowired
	CompanyPaymentMapper companyPaymentMapper;
	@Autowired
	RedisService redisService;

	@Override
	public void checkCompanyPayPassword(int compid, String inputPwd) {
		CompanyAccount companyAccount = new CompanyAccount().selectOne(Condition.create().eq("compid", compid));
		if (companyAccount == null) {
			throw new SmartException(StatusMsg.StatusMsg_302);
		}

		String pwdDescrypt = "";
		try {
			pwdDescrypt = DESUtil.decrypt(inputPwd, Constants.PWD_DES_KEY);
		} catch (Exception e) {
			log.error("密码解密失败：", e);
		}
		String md5Pwd = MD5Util.md5(pwdDescrypt + companyAccount.getSalt());
		// 支付密码连错3次将被锁定，选择重置（忘记密码功能，重置后即可解封）或等待 3小时
		String key = RedisKey.genCompanyPapPasswordKey(compid);
		int times = redisService.getInt(key);
		if (times > 3) {
			throw new SmartException(StatusMsg.StatusMsg_496).setData(times);
		}
		if (!md5Pwd.equals(companyAccount.getPayPassword())) {
			times = times + 1;
			redisService.set(RedisKey.genCompanyPapPasswordKey(compid), times, 3 * 60 * 60);
			if (times >= 3) {
				throw new SmartException(StatusMsg.StatusMsg_496).setData(times);
			}
			// 记录失败次数+1
			throw new SmartException(StatusMsg.StatusMsg_113).setData(times);
		} else {
			// 输入正确，清空密码错误验证key
			redisService.del(key);
		}
	}

	@Override
	public CompanyDetailDto getCompanyInfo(int compid) {
		CompanyDetailDto detailDto = companyMapper.getCompanyInfo(compid);

		// 获取 默认支付配置
		CompanyParty zddParty = getCompanyDefaultPartyZdd(compid);
		if(zddParty != null){
			detailDto.setPartyId(zddParty.getPartyId());
			detailDto.setPartyName(zddParty.getPartyName());
		}
		// 获取智零工默认支付配置
		CompanyParty oddParty = getCompanyDefaultPartyOdd(compid);
		if(oddParty != null && oddParty.getTaxSourceId() != null){
			TaxSource taxSource = new TaxSource().selectById(oddParty.getTaxSourceId());
			if(taxSource != null){
				detailDto.setTaxSourceId(taxSource.getTaxSourceId());
				detailDto.setTaxSourceName(taxSource.getTaxSourceName());
				detailDto.setTaxSourceCostRate(taxSource.getTaxSourceCostRate());
			}
		}
		// 获取创客团配置

		return detailDto;
	}

	/**
	 * 企业支付前校验- 业务
	 * @param compid
	 */
	@Override
	public void checkCompanyPayBeforeZdd(int compid) {
		Company company = new Company().selectById(compid);
		CompanyAccount companyAccount = new CompanyAccount().selectOne(Condition.create().eq("compid", compid));
		// 基础校验
		checkCompanyBase(company,companyAccount);
		//  业务是否开启
		if(!company.getOpenZdd()){
			throw new SmartException(StatusMsg.StatusMsg_353);
		}
	}

	@Override
	public void checkCompanyPayBeforeCroOrOdd(int compid, int workType) {
		Company company = new Company().selectById(compid);
		CompanyAccount companyAccount = new CompanyAccount().selectOne(Condition.create().eq("compid", compid));
		// 基础校验
		checkCompanyBase(company, companyAccount);
		if (workType == Constants.WORK_TYPE_1) {
			// 智众包业务是否开启
			if (!NumberUtil.equals(2, company.getIntelCrowdsource())) {
				throw new SmartException(StatusMsg.StatusMsg_352);
			}
		} else {
			// 智零工业务是否开启
			if (!NumberUtil.equals(1, company.getOpenOddJob())) {
				throw new SmartException(StatusMsg.StatusMsg_378);
			}
		}
	}

	/**
	 * 企业支付前的基础校验
	 * 		1.检查是否可交易状态
	 *
	 * @param company
	 */
	public void checkCompanyBase(Company company,CompanyAccount companyAccount){
		if(!NumberUtil.equals(2,companyAccount.getTradeFlag())){
			throw new SmartException(StatusMsg.StatusMsg_385);
		}
	}

	@Override
	public CompanyParty getCompanyDefaultPartyZdd(Integer compid) {
		return companyPartyMapper.getCompanyDefault(compid, Constants.BUSINESS_SN_ZDD);
	}

	@Override
	public CompanyParty getCompanyDefaultPartyCro(Integer compid) {
		return companyPartyMapper.getCompanyDefault(compid, Constants.BUSINESS_SN_CRO);
	}

	@Override
	public CompanyParty getCompanyDefaultPartyOdd(Integer compid) {
		return companyPartyMapper.getCompanyDefault(compid, Constants.BUSINESS_SN_ODD);
	}

	@Override
	public CompanyParty getCompanyDefaultPartyMul(Integer compid, int workType) {
		if (workType == Constants.WORK_TYPE_1) {
			return getCompanyDefaultPartyCro(compid);
		} else if (workType == Constants.WORK_TYPE_2) {
			return getCompanyDefaultPartyOdd(compid);
		}
		return null;
	}

	@Override
	public CompanyParty getCompanyDefaultPartyGroup(Integer compid) {
		return companyPartyMapper.getCompanyDefault(compid, Constants.BUSINESS_SN_GROUP);
	}

	@Override
	public CompanyPayBalanceDto getCompanyDefaultBalanceZdd(Integer compid) {
		CompanyParty companyParty = getCompanyDefaultPartyZdd(compid);
		return getCompanyPayBalanceDto(compid, companyParty);
//		return companyPartyMapper.getCompanyWithBalance(compid,Constants.BUSINESS_SN_ZDD, 1).get(0);
	}

	@Override
	public CompanyPayBalanceDto getCompanyDefaultBalanceCro(Integer compid) {
		CompanyParty companyParty = getCompanyDefaultPartyCro(compid);
		return getCompanyPayBalanceDto(compid, companyParty);
	}

	@Override
	public CompanyPayBalanceDto getCompanyDefaultBalanceOdd(Integer compid) {
		CompanyParty companyParty = getCompanyDefaultPartyOdd(compid);
		return getCompanyPayBalanceDto(compid, companyParty);
	}

	@Override
	public CompanyPayBalanceDto getCompanyDefaultBalanceGroup(Integer compid) {
		CompanyParty companyParty = getCompanyDefaultPartyGroup(compid);
		return getCompanyPayBalanceDto(compid, companyParty);
	}

	@Override
	public List<CompanyPayBalanceDto> getCompanyDefaultBalanceList(Integer compid) {
		List<CompanyPayBalanceDto> list = new ArrayList<>();
		CompanyPayBalanceDto zdd = getCompanyDefaultBalanceZdd(compid);
		if (zdd != null) {
			list.add(zdd);
		}
		CompanyPayBalanceDto cro = getCompanyDefaultBalanceCro(compid);
		if (cro != null) {
			list.add(cro);
		}
		CompanyPayBalanceDto odd = getCompanyDefaultBalanceOdd(compid);
		if (odd != null) {
			list.add(odd);
		}
		CompanyPayBalanceDto group = getCompanyDefaultBalanceGroup(compid);
		if (group != null) {
			list.add(group);
		}
		return list;
	}

	@Override
	public Map<String, List<CompanyPayBalanceDto>> getCompanyDefaultBalanceMap(Integer compid) {
		List<CompanyPayBalanceDto> list = getCompanyDefaultBalanceList(compid);
		return list.stream().collect(Collectors.groupingBy(CompanyPayBalanceDto::getBusinessSn));
	}

	@Override
	public List<CompanyPayBalanceDto> getCompanyAllBalanceList(Integer compid) {
		return companyPartyMapper.getCompanyWithBalance(compid,null, null);
	}

	@Override
	public BigDecimal getCompanyTotalBalance(Integer compid) {
		return companyPartyMapper.getCompanyTotalBalance(compid);
	}

	@Override
	public CompanyPayment getCompanyPayment(Integer compid,Integer payId) {
		return companyPaymentMapper.getCompanyPayment(compid, payId);
	}

	// 组装数据
	private CompanyPayBalanceDto getCompanyPayBalanceDto(Integer compid, CompanyParty companyParty) {
		if(companyParty == null){
			return null;
		}

		CompanyPayment companyPayment = companyPaymentMapper.getCompanyPayment(compid, companyParty.getPayId());
		CompanyPayBalanceDto dto = new CompanyPayBalanceDto();
		BeanUtils.copyProperties(companyParty, dto);
		dto.setBalance(companyPayment.getBalance());
		dto.setFrozenBalance(companyPayment.getFrozenBalance());
		return dto;
	}
}
